package cn.tedu.charging.order.rabbitmq;

import cn.tedu.charging.order.config.RabbitMQConfig;
import cn.tedu.charging.order.dao.repository.OrderRepository;
import cn.tedu.charging.order.pojo.po.OrderMQPO;
//java代码里有很多的Message不要import 错了
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
//java代码里有很多的Message不要import 错了
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * rabbit-mq 消费者 消费的是死信队列
 */
@Slf4j
@Component
public class RabbitMQOrderConsumer {

    @Autowired
    private OrderRepository orderRepository;

    @RabbitListener(queues = RabbitMQConfig.ORDER_DEAD_LETTER_QUEUE)
    public void orderDeadLetter(OrderMQPO orderMQPO, Message message, Channel channel) throws Exception {
        log.info("Order dead letter queue:{}",orderMQPO);
        //如何保证消息不丢失 ? 发的时候不丢,queue和Exchange 开启持久化,手动ack
        //消息队列中的ack是什么意思?
        //消费者 拿到消息,处理业务 更新订单状态
        // 正常情况
        // 更新订单状态成功 ,返回ack给消息队列,
        // 消息队列收到ack后,认为你是消费成功了,会把这个条消息从消息队列删除,消费者继续消费下一条消息
        // 异常情况
        // 数据库出现异常，更新失败，不返回ack给消息队列,
        // 消息队列没有收到ack,认为消费不成功,不会把消息从消息队列删除,消息队列会把这条消息一直保存
        //等我数据库修好了继续重复消费者条消息,数据没丢,继续更新订单的状态

        //把正在充电中的订单状态改为异常结束
        //条件 orderNo,bill_status = 1 结果 bill_status 1 ==> 3
        //two to 2
        orderRepository.updateOrderStatusFromProcess2ExceptionEnd(orderMQPO.getOrderNo());
        //手动ack
        long deliveryTag = message.getMessageProperties().getDeliveryTag();
        channel.basicAck(deliveryTag,true);

    }
}
